﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

using Skyhook.Core.Graphics;
using Skyhook.Core.Graphics.Options;
using Skyhook.Core.Input;
using Skyhook.Core.Configuration;

namespace Skyhook.Core
{
    public class Application : ApplicationComponent, IDisposable
    {
        XNAGameComponent XNAComponent = null;
        Game XNAGame = null;
        DataStorage _Data = null;

        public Application()
            : base()
        {
            XNAGame = new Game();
            XNAComponent = new XNAGameComponent(XNAGame);

            XNAGame.Components.Add(XNAComponent);

            XNAComponent.OnLoadContent += LoadContentWithComponents;
            XNAComponent.OnUnloadContent += UnloadContentWithComponents;
            XNAComponent.OnInitialize += InitializeApplicationServices;
            XNAComponent.OnInitialize += InitializeWithComponents;
            XNAComponent.OnUpdate += UpdateApplicationServices;
            XNAComponent.OnUpdate += UpdateWithComponents;
            XNAComponent.OnDraw += DrawWithComponents;

            _Data = new DataStorage();
            Data = _Data;
            Data.RegisterDataType<GraphicsData>();
            Data.LoadSingleDataTypeFromPath<GraphicsData>("config");

            GraphicsManager.Initialize(XNAGame, Data.GetData<GraphicsData>("options"));

            XNAGame.IsMouseVisible = true;
            XNAGame.IsFixedTimeStep = false;
        }

        public override Application Root
        {
            get
            {
                return this;
            }
        }

        public void Run()
        {
            XNAGame.Run();
        }

        public void Exit()
        {
            XNAGame.Exit();
        }

        public bool IsActive
        {
            get
            {
                return XNAGame.IsActive;
            }
        }

        public void ResetElapsedTime()
        {
            XNAGame.ResetElapsedTime();
        }

        void InitializeApplicationServices()
        {
            XNAGame.Content.RootDirectory = "";
            GraphicsFactory.Initialize(XNAGame.GraphicsDevice, XNAGame.Content);
            GraphicsManager.SetGraphicsDevice(XNAGame.GraphicsDevice);
            StreamFactory.Initialize("data");
        }

        void UpdateApplicationServices(GameTime time)
        {
            InputEvents.Update();
        }

        void IDisposable.Dispose()
        {
            XNAGame.Dispose();
        }
    }
}
